// 求组合数 高精度 线性筛
// 给定两个整数 n, m（1 <= m <= n <= 10000），求 C(n, m)
// 相关帖子 ：https://www.cnblogs.com/dx123/p/16770320.html

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 10010;
int prime[MAXN];
bool visited[MAXN];
int cnt;

// 线性筛
void getprime(int n)
{
    for(int i = 2; i <= n; ++i)
    {
        if(!visited[i]) prime[cnt++] = i;
        for(int j = 0; i * prime[j] <= n; ++j)
        {
            visited[i * prime[j]] = true;
            if(i % prime[j] == 0) break;
        }
    }
}

// 返回 n! 中质数 p 的个数
// ans = n / p + n / p^2 + n / p^3 + ...
int getp(int n, int p)
{
    int ans = 0;
    while(n)
    {
        ans += n / p;
        n /= p;
    }
    return ans;
}

// C(n, m) 中 p 的个数
int getps(int n, int m, int p)
{
    return getp(n, p) - getp(m, p) - getp(n - m, p);
}

// 高精度乘法
void mul(int* C, int p, int& len)
{
    int t = 0;
    for(int i = 0; i < len; ++i)
    {
        t += C[i] * p;
        C[i] = t % 10;
        t /= 10;
    }
    while(t)
    {
        C[len++] = t % 10;
        t /= 10;
    }
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    getprime(n);
    int C[MAXN], len = 1;
    C[0] = 1;
    for(int i = 0; i < cnt; ++i)
    {
        int p = prime[i];
        int s = getps(n, m, p);
        while(s--) mul(C, p, len);
    }
    for(int i = len - 1; i >= 0; --i) printf("%d", C[i]);
    puts("");

    return 0;
}